﻿/*
   Copyright 2012 University of Southampton

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace uk.ac.soton.ses
{
    /// <summary>
    /// Provides a wrapper class for parsing a medical stats file with a specifiable delimiter
    /// </summary>
    public class FileParser_Stats
    {
        private string _fileName = "";
        private char _delim;

        /// <summary>
        /// Dataset names, zero-based indexed by dataset/column number
        /// </summary>
        public Dictionary<int, string> DatasetNames{get;set;}

        /// <summary>
        /// Field names, zero-based indexed by field/row number
        /// </summary>
        public Dictionary<int, string> FieldNames { get; set; }

        /// <summary>
        /// Field values, zero-based indexed by dataset/column number and then by field/row number (using numbers not names in case names are repeated)
        /// </summary>
        public Dictionary<int, Dictionary<int, string>> FieldValues { get; set; }

        /// <summary>
        /// The number of lines found in the parsed file
        /// </summary>
        public int LineCount { get; set; }

        /// <summary>
        /// Constructor with parameters relating to how to find and parse the file
        /// </summary>
        /// <param name="fileName">The path to the file to parse</param>
        /// <param name="delim">The delimiter to use</param>
        public FileParser_Stats(string fileName, char delim)
        {
            this._fileName = fileName;
            this._delim = delim;
            this.ReadFile();
        }

        /// <summary>
        /// Read the file with the configured delimiter to set DatasetNames, FieldNames and FieldValues.
        /// </summary>
        private void ReadFile()
        {
            using (StreamReader sr = new StreamReader(this._fileName))
            {
                this.DatasetNames = new Dictionary<int, string>();
                this.FieldNames = new Dictionary<int, string>();
                this.FieldValues = new Dictionary<int, Dictionary<int, string>>();
                string line = null;

                //Keep track of how many lines we have in the file
                this.LineCount = 0;

                while ((line = sr.ReadLine()) != null)
                {
                    this.LineCount++;

                    //Keep track of which column we're on
                    int fieldno = 1;

                    //The first line has the names of the datasets
                    if (this.LineCount == 1)
                    {
                        foreach (string datasetname in line.Split(this._delim))
                        {
                            //Skip first column as it is not a dataset (the title of the field column)
                            if (fieldno == 1)
                            {
                                fieldno++;
                                continue;
                            }

                            this.DatasetNames.Add(fieldno - 1, datasetname);
                            fieldno++;
                        }
                    }

                    //Get the field names from the first column of lines numbers > 1
                    else
                    {
                        foreach (string field in line.Split(this._delim))
                        {
                            if (fieldno == 1)
                            {
                                this.FieldNames.Add(this.LineCount - 2, field);
                            }
                            else
                            {
                                if (!this.FieldValues.ContainsKey(fieldno - 1))
                                {
                                    this.FieldValues.Add(fieldno - 1, new Dictionary<int, string>());
                                }
                                Dictionary<int, string> fieldDictionary = this.FieldValues[fieldno - 1];
                                fieldDictionary[this.LineCount - 2] = field;
                            }
                            fieldno++;
                        }
                    }
                }
            }
        }
    }

}
